﻿using System;
using System.Collections.Generic;
using System.Drawing;
using System.Linq;
using System.Text;

namespace WallpaperGenerator
{
    public struct Color
    {
        public static Color FromDC(System.Drawing.Color c)
        {
            return (Color)c;
        }

        public static Color Empty = new Color(-1, -1, -1, -1);

        public double R;
        public double G;
        public double B;
        public double A;

        public Color(double r, double g, double b)
            : this(r, g, b, 1.0)
        {
        }

        public Color(double r, double g, double b, double a)
        {
            this.R = r;
            this.G = g;
            this.B = b;

            this.A = a;
        }

        public Color Normalize()
        {
            return new Color(
                Math.Min(1.0, Math.Max(0, this.R)),
                Math.Min(1.0, Math.Max(0, this.G)),
                Math.Min(1.0, Math.Max(0, this.B)),
                Math.Min(1.0, Math.Max(0, this.A)));
        }

        public static Color operator +(Color l, Color r)
        {
            return new Color(
                l.R + r.R,
                l.G + r.G,
                l.B + r.B,
                l.A + r.A);
        }

        public static Color operator -(Color l, Color r)
        {
            return new Color(
                l.R - r.R,
                l.G - r.G,
                l.B - r.B,
                l.A - r.A);
        }

        public static Color operator *(Color l, Color r)
        {
            return new Color(
                l.R * r.R,
                l.G * r.G,
                l.B * r.B,
                l.A * r.A);
        }

        public static Color operator /(Color l, Color r)
        {
            return new Color(
                l.R / r.R,
                l.G / r.G,
                l.B / r.B,
                l.A / r.A);
        }

        public static Color operator +(Color l, double r)
        {
            return new Color(
                l.R + r,
                l.G + r,
                l.B + r,
                l.A + r);
        }

        public static Color operator -(Color l, double r)
        {
            return new Color(
                l.R - r,
                l.G - r,
                l.B - r,
                l.A - r);
        }

        public static Color operator *(Color l, double r)
        {
            return new Color(
                l.R * r,
                l.G * r,
                l.B * r,
                l.A * r);
        }

        public static Color operator *(double l, Color r)
        {
            return new Color(
                r.R * l,
                r.G * l,
                r.B * l,
                r.A * l);
        }

        public static Color operator /(Color l, double r)
        {
            return new Color(
                l.R / r,
                l.G / r,
                l.B / r,
                l.A / r);
        }

        public Color Interpolate(Color color, double amount)
        {
            Color tn = this.Normalize();
            Color cn = color.Normalize();

            return new Color(
                (tn.R * (1.0 - amount)) + (cn.R * amount),
                (tn.G * (1.0 - amount)) + (cn.G * amount),
                (tn.B * (1.0 - amount)) + (cn.B * amount),
                (tn.A * (1.0 - amount)) + (cn.A * amount));
        }

        public static implicit operator Color(System.Drawing.Color color)
        {
            return new Color(
                color.R / 255.0,
                color.G / 255.0,
                color.B / 255.0,
                color.A / 255.0);
        }

        public static implicit operator System.Drawing.Color(Color color)
        {
            return System.Drawing.Color.FromArgb(
                Math.Min(255, Math.Max((int)(color.A * 255), 0)),
                Math.Min(255, Math.Max((int)(color.R * 255), 0)),
                Math.Min(255, Math.Max((int)(color.G * 255), 0)),
                Math.Min(255, Math.Max((int)(color.B * 255), 0)));
        }

        public override string ToString()
        {
            return string.Format("R: {0} G: {1} B: {2} A: {3}", this.R, this.G, this.B, this.A);
        }
    }
}
